<?php
/**
 * Controller_Request
 * 
 * 作者:  姚刚 (yaogang@the9sense.com)
 * 创建时间: 2011-02-24 00:15:30
 * 修改记录: 
 * 
 * $Id: Request.php 7 2011-03-16 05:07:39Z coosuu@gmail.com $
 */

class Controller_Request {

    private static $_instance = null;

    public function __construct() {

    }

    public static function &getInstance() {

        if (!self::$_instance) {
            self::$_instance = new self;
        }
        return self::$_instance;
    }

    /**
     * get
     * 获取请求的GET参数
     *
     * @param  string $key
     * @param  mixed $default key不存在时的默认值
     * @return mixed
     */
    public function get($key, $default = null) {
        if (array_key_exists($key, $_GET)) {
            return $_GET[$key];
        }
        return $default;
    }

    /**
     * getx
     * 根据指定多个KEY返回相关数组
     *
     * @params string 要获取的keys，如果为空则返回所有GET参数
     * @return array
     */
    public function getx() {

        $keys = func_get_args();
        if (is_array($keys[0])) {
            $keys = $keys[0];
        }

        $result = array();

        if (!$keys) {
            return $_GET;
        }

        foreach ($keys as $key) {
            if (array_key_exists($key, $_GET)) {
                $result[$key] = $_GET[$key];
            }
        }

        return $result;
    }

    /**
     * post
     * 获取请求的POST参数
     *
     * @param string $key
     * @param mixed  $default key不存在时的默认值
     * @return mixed
     */
    public function post($key, $default = null) {

        if (array_key_exists($key, $_POST)) {
            return $_POST[$key];
        }

        return $default;
    }

    /**
     * postx
     * 根据指定多个KEY返回相关数组
     *
     * @params string 要获取的keys，如果为空则返回所有POST参数
     * @return array
     */
    public function postx() {

        $keys = func_get_args();
        if ($keys && is_array($keys[0])) {
            $keys = $keys[0];
        }

        $result = array();

        if (!$keys) {
            return $_POST;
        }

        foreach ($keys as $key) {
            if (array_key_exists($key, $_POST)) {
                $result[$key] = $_POST[$key];
            }
        }

        return $result;
    }

    /**
     * cookie
     * 获取COOKIE值
     *
     * @param stirng $key
     * @param mixed  $default
     * @return mixed
     */
    public function cookie($key, $default = null) {
        if (array_key_exists($key, $_COOKIE)) {
            return $_COOKIE[$key];
        }
        return $default;
    }

    /**
     * cookiex
     * 据指定多个KEY返回相关数组
     *
     * @return array
     */
    public function cookiex() {
        $keys = func_get_args();
        if (is_array($keys[0])) {
            $keys = $keys[0];
        }

        $result = array();

        if (!$keys) {
            return $_COOKIE;
        }

        foreach ($keys as $key) {
            if (array_key_exists($key, $_COOKIE)) {
                $result[$key] = $_COOKIE[$key];
            }
        }

        return $result;
    }

    /**
     * server
     *
     * @param stirng $key
     * @param mixed  $default
     * @return mixed
     */
    public function server($key, $default = null) {
        if (array_key_exists($key, $_SERVER)) {
            return $_SERVER[$key];
        }
        return $default;
    }

    /**
     * serverx
     * 根据指定多个KEY返回相关数组
     *
     * @params string 要获取的keys，如果为空则返回所有$_SERVER参数
     * @return array
     */
    public function serverx() {
        $result = array();
        $keys = func_get_args();
        foreach ($keys as $key) {
            $result[$key] = $this->server($key);
        }
        return $result;
    }

    /**
     * env
     * 获取$_ENV环境变量
     *
     * @param string $key
     * @param mixed  $default
     * @return mixed
     */
    public function env($key, $default = null) {
        if (array_key_exists($key, $_ENV)) {
            return $_ENV[$key];
        }
        return $default;
    }

    /**
     * envx
     * 根据指定多个KEY返回相关数组
     *
     * @params string 要获取的keys，如果为空则返回所有$_ENV参数
     * @return array
     */
    public function evnx() {
        $result = array();
        $keys = func_get_args();
        foreach ($keys as $key) {
            $result[$key] = $this->env($key);
        }
        return $result;
    }

    /**
     * getMethod
     * 获取HTTP请求方式
     *
     * @return string
     */
    public function getMethod() {
        return $this->server('REQUEST_METHOD');
    }

    /**
     * isPost
     * 判断是否为POST请求
     *
     * @return boolean
     */
    public function isPost() {
        if ("POST" == $this->getMethod()) {
            return true;
        }
        return false;
    }

    /**
     * getClientIp
     * 获取客户端IP
     *
     * @return string
     */
    public function getClientIp() {
        $ip = FALSE;

        // 直接IP
        if ($this->server('HTTP_CLIENT_IP')) {
            $ip = $this->server('HTTP_CLIENT_IP');
        }

        // 代理
        if ($this->server('HTTP_X_FORWARDED_FOR')) {

            $ips = explode (", ", $this->server('HTTP_X_FORWARDED_FOR'));
            if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }

            for ($i = 0; $i < count($ips); $i++) {
                if (!preg_match('/^(?:10|172\.(?:1[6-9]|2\d|3[01])|192\.168)\./', $ips[$i])) {
                    if (version_compare(phpversion(), "5.0.0", ">=")) {
                        if (ip2long($ips[$i]) != false) {
                            $ip = $ips[$i];
                            break;
                        }
                    } else {
                        if (ip2long($ips[$i]) != -1) {
                            $ip = $ips[$i];
                            break;
                        }
                    }
                }
            }
        }

        if (!$ip) {
            return $this->server('REMOTE_ADDR');
        }

        return $ip;
    }

    /**
     * file
     * 根据key获取$_FILES
     *
     * @param  string $key
     * @param  mixed $default
     * @return mixed
     */
    public function file($key, $default = null) {
        if (array_key_exists($key, $_FILES)) {
            return $_FILES[$key];
        }
        return $default;
    }

    /**
     * filex
     * 根据多个KEY返回相关文件结果
     * 
     * @return array
     */
    public function filex() {
        $result = array();
        $keys = func_get_args();
        if (!$keys) {
            return $_FILES;
        }
        foreach ($keys as $key) {
            $result[$key] = $this->file($key);
        }
        return $result;
    }

    /**
     * header
     * 获取header
     *
     * @param  string $key
     * @param  mixed $default
     * @return mixed
     */
    public function header($key, $default = null) {
        if (!$key) {
            return false;
        }

        $sKey = 'HTTP_' . strtoupper(str_replace('-', '_', $key));
        if (isset($_SERVER[$sKey])) {
            return $_SERVER[$sKey];
        }

        if (function_exists('apache_request_headers')) {
            $headers = apache_request_headers();
            if (isset($headers[$key])) {
                return $headers[$key];
            }
        }

        return $default;
    }

    /**
     * headerx
     * 获取多个header值
     * 
     * @return void
     */
    public function headerx() {
        $result = array();
        $keys = func_get_args();
        if (!$keys) {
            return apache_request_headers();
        }
        foreach ($keys as $key) {
            $result[$key] = $this->header($key);
        }
        return $result;
    }

    /**
     * isXmlHttpRequest
     * 判断是否为ajax请求
     *
     * 目前支持判断如下js类库发起的ajax请求：
     *  + Prototype 及 Prototype 系的类库（例如Scriptaculous）
     *  + YUI
     *  + jQuery
     *  + MochiKit
     *
     * @return boolean
     */
    public function isXmlHttpRequest() {
        return $this->header('X_Requested_With') == 'XMLHttpRequest';
    }

    /**
     * xmlHttpRequestType
     * 获取ajax请求类型
     *
     * 目前仅对jQuery有效
     *
     * @return void
     */
    public function xmlHttpRequestType() {

        if ($this->isXmlHttpRequest()) {
            switch ($this->header('Accept')){
                case 'application/json, text/javascript, */*':
                    return 'json';
                case 'text/javascript, application/javascript, */*':
                    return 'javascript';
                case 'text/html, */*':
                    return 'html';
                case 'application/xml, text/xml, */*':
                    return 'xml';
                case 'text/plain, */*':
                    return 'text';
            }
        }

        return false;
    }

}
